package com.gengzp.permission.utils;

import com.gengzp.permission.core.PermissionCoreFunc;
import com.gengzp.permission.exception.PermissionException;
import com.gengzp.permission.model.UserPrincipalModel;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName PermissionUtils
 * @Description 权限认证工具类
 * <p> 该工具类提供了权限认证相关方法 </p>
 * <p> 1.登录,注销,踢出核心方法 </p>
 * <p> 2.当前用户信息相关方法 </p>
 * <p> 3.角色权限缓存相关方法 </p>
 * <p> 4.超级管理员相关方法 </p>
 * @Author gengzp
 * @Date 2025/8/14 21:33
 */
@Component
public class PermissionUtils {

    private static PermissionCoreFunc permissionCoreFunc;

    public PermissionUtils(PermissionCoreFunc permissionCoreFunc) {
        PermissionUtils.permissionCoreFunc = permissionCoreFunc;
    }

    // ================================================================
    // ===================== 【登录,注销,踢出核心方法】 ===================
    // ================================================================

    /**
     * 用户登录
     *
     * @param userId     用户id
     * @param clientType 登录客户端类型
     * @param roleIds    用户角色id集合
     * @return UserPrincipalModel 本次成功登录的用户完整认证信息
     */
    public static UserPrincipalModel doLogin(Object userId, Object clientType, Collection<?> roleIds) throws PermissionException {
        return permissionCoreFunc.login(String.valueOf(userId), String.valueOf(clientType),
                roleIds.stream().map(String::valueOf).collect(Collectors.toList()));
    }

    /**
     * 用户退出
     *
     * @param userId 用户id
     * @param token  当前在线的用户token
     */
    public static void doQuit(Object userId, Object token) {
        permissionCoreFunc.quit(String.valueOf(userId), String.valueOf(token));
    }

    /**
     * 踢出用户
     *
     * @param userId 用户id
     */
    public static void doKickOut(Object userId) throws PermissionException {
        permissionCoreFunc.kickOut(String.valueOf(userId));
    }


    // =============================================================
    // ===================== 【当前用户信息相关方法】===================
    // =============================================================

    /**
     * 获取当前请求中的完整用户认证信息
     *
     * @return 完整用户认证信息
     */
    public static UserPrincipalModel getCurrentUserPrincipalModel() {
        return permissionCoreFunc.getCurrentUserPrincipalModelFromThreadLocal();
    }

    /**
     * 获取当前请求中的用户id
     *
     * @return 当前请求中的用户id
     */
    public static String getCurrentUserId() {
        return Optional.ofNullable(getCurrentUserPrincipalModel()).map(UserPrincipalModel::getUserId).orElse(null);
    }

    /**
     * 获取当前请求中的用户token
     *
     * @return 当前请求中的用户token
     */
    public static String getCurrentUserToken() {
        return Optional.ofNullable(getCurrentUserPrincipalModel()).map(UserPrincipalModel::getToken).orElse(null);
    }

    /**
     * 获取当前请求中的用户拥有的所有权限编码集合
     *
     * @return 当前请求中的用户拥有权限编码集合
     */
    public static Set<String> getCurrentUserOwnedPermissionCodes() throws PermissionException {
        return permissionCoreFunc.getCurrentUserOwnedPermissionCodes();
    }

    // ==============================================================
    // ===================== 【角色权限缓存相关方法】 ===================
    // ==============================================================

    /**
     * 为角色分配权限, 保存在缓存中
     *
     * @param roleId          角色id
     * @param permissionCodes 权限编码集合
     * @param isReplace       是否替换标识, 0:新增; 1: 替换掉当前角色已有权限
     */
    public static void assignCacheRolePermissions(Object roleId, Collection<?> permissionCodes, boolean isReplace) throws PermissionException {
        permissionCoreFunc.assignCacheRolePermissions(String.valueOf(roleId),
                (permissionCodes == null || permissionCodes.isEmpty()) ? new ArrayList<>() :
                        permissionCodes.stream().map(String::valueOf).collect(Collectors.toList()),
                isReplace);
    }

    /**
     * 为用户分配角色, 保存在缓存中
     *
     * @param userId    用户id
     * @param roleIds   角色id集合
     * @param isReplace 是否替换标识, 0:新增; 1: 替换掉当前用户已绑角色
     */
    public static void assignCacheUserRoles(Object userId, Collection<?> roleIds, boolean isReplace) throws PermissionException {
        permissionCoreFunc.assignCacheUserRoles(String.valueOf(userId),
                (roleIds == null || roleIds.isEmpty() ? new ArrayList<>() :
                        roleIds.stream().map(String::valueOf).collect(Collectors.toList())),
                isReplace);
    }

    /**
     * 移除缓存中的指定id的角色数据
     *
     * @param roleId 角色id
     */
    public static void removeCacheRole(Object roleId) throws PermissionException {
        permissionCoreFunc.removeCacheRole(String.valueOf(roleId));
    }

    /**
     * 移除缓存中所有角色数据
     */
    public static void removeAllCacheRoles() throws PermissionException {
        permissionCoreFunc.removeAllCacheRoles();
    }

    /**
     * 根据角色id获取角色拥有的权限编码集合
     *
     * @param roleId 角色id
     * @return 角色拥有的权限编码集合
     */
    public static Set<String> getRolePermissionCodes(Object roleId) throws PermissionException {
        return permissionCoreFunc.getRolePermissionCodes(String.valueOf(roleId));
    }

    /**
     * 根据角色id集合获取所有拥有的权限编码集合
     *
     * @param roleIds 角色id集合
     * @return 所有拥有的权限编码集合
     */
    public static Set<String> getRolePermissionCodes(Collection<?> roleIds) throws PermissionException {
        return (roleIds == null || roleIds.isEmpty() ? new HashSet<>() :
                permissionCoreFunc.getRolePermissionCodes(
                        roleIds.stream().map(String::valueOf).collect(Collectors.toSet())));
    }

    /**
     * 获取所有缓存中的角色id
     *
     * @return 角色id集合
     */
    public static List<String> getAllCacheRoleIds() {
        return permissionCoreFunc.getAllCacheRoleIds();
    }

    // =============================================================
    // ===================== 【超级管理员相关方法】 ====================
    // =============================================================

    /**
     * 校验用户是否为超级管理员
     *
     * @param userId 用户id
     * @return true:是超级管理员; false:非超级管理员
     */
    public static Boolean verifyUserIsSuperAdmin(Object userId) {
        return userId != null && !String.valueOf(userId).isBlank() && String.valueOf(userId).equals(getSuperAdminUserId());
    }

    /**
     * 获取超级管理员用户id
     *
     * @return 超级管理员用户id
     */
    public static String getSuperAdminUserId() {
        return permissionCoreFunc.getSuperAdminUserId();
    }

    /**
     * 获取超级管理员用户账号
     *
     * @return 获取超级管理员用户账号
     */
    public static String getSuperAdminUserAccount() {
        return permissionCoreFunc.getSuperAdminUserAccount();
    }

    /**
     * 获取超级管理员用户昵称
     *
     * @return 获取超级管理员用户昵称
     */
    public static String getSuperAdminNickname() {
        return permissionCoreFunc.getSuperAdminNickname();
    }

    /**
     * 获取超级管理员用户密码
     *
     * @return 获取超级管理员用户密码
     */
    public static String getSuperAdminUserPassword() {
        return permissionCoreFunc.getSuperAdminUserPassword();
    }

    /**
     * 获取超级管理员用户加密盐值
     *
     * @return 获取超级管理员用户加密盐值
     */
    public static String getSuperAdminUserSalt() {
        return permissionCoreFunc.getSuperAdminUserSalt();
    }

}

